package org.vdab.projects.tasks.client.entities;

import java.util.Set;

import org.vdab.projects.tasks.client.dal.GWTEntityManager;
import org.vdab.projects.tasks.client.util.DelayedList;
import org.vdab.projects.tasks.client.util.ICommand;
import org.vdab.projects.tasks.shared.entities.IBaseEntity;
import org.vdab.projects.tasks.shared.entities.ITask;
import org.vdab.projects.tasks.shared.entities.ITaskBook;
import org.vdab.projects.tasks.shared.entities.ITaskList;
import org.vdab.projects.tasks.shared.entities.impl.Task;
import org.vdab.projects.tasks.shared.entities.impl.TaskList;

import com.google.gwt.user.client.rpc.AsyncCallback;

public class ClientTaskList extends ClientEntity<TaskList> implements ITaskList {

	protected ClientTaskList(TaskList sso, GWTEntityManager gwtEntityManager) {
		super(sso, gwtEntityManager);
	}

	public ClientTaskList(String key, GWTEntityManager gwtEntityManager) {
		super(key, gwtEntityManager);
	}

	@Override
	protected void load(String key, AsyncCallback<TaskList> onLoaded) {
		getManager().loadTaskListByKey(key, onLoaded);
	}

	@Override
	public IBaseEntity<TaskList> save() throws Exception {
		super.execute(new ICommand<TaskList>() {
			@Override
			public void execute(TaskList entity) throws Exception {
				getManager().saveTaskList(entity);
			}
		});
		return this;
	}

	@Override
	public void addToTodobook(final ITaskBook taskBook) throws Exception {
		super.execute(new ICommand<TaskList>() {
			@Override
			public void execute(TaskList entity) throws Exception {
				entity.addToTodobook(taskBook);
			}
		});
	}

	@Override
	public void addTask(final ITask task) throws Exception {
		super.execute(new ICommand<TaskList>() {			
			@Override
			public void execute(final TaskList entityTaskList) throws Exception {
				task.execute(new ICommand<Task>() {					
					@Override
					public void execute(Task entityTask) throws Exception {
						entityTaskList.addTask(task); 
					}
				});				
			}
		});
	}

	public DelayedList<ITask> getClientTasks(final DelayedList<ITask> myTasks) throws Exception {
		super.execute(new ICommand<TaskList>() {			
			@Override
			public void execute(TaskList entityTaskList) throws Exception {
				for(ITask t : entityTaskList.getTasks()){
					t.execute(new ICommand<Task>() {						
						@Override
						public void execute(Task entityTask) throws Exception {
							myTasks.add(entityTask);							
						}
					});
				}
			}
		});
		return myTasks;
	}

	@Override
	public Set<ITask> getTasks() throws Exception {
		return getClientTasks(new DelayedList<ITask>());
	}

	//Consider moving it to TaskList (the shared one)
	public ITask createNewTask() throws Exception {
		final ITask task = new Task().init().setDescription("New Task"); //new ClientTask() when implemented
		this.execute(new ICommand<TaskList>() {			
			@Override
			public void execute(TaskList entity) throws Exception {
				entity.addTask(task);
				entity.save();
			}
		});		
		return task;
	}
}
